import fasttoolpanel from "../graph/extendGraph/fasttoolpanel";
import { LGXEnums } from "../common/sysenum";


import utilfuncs from "../common/tools/utilfuncs";
var funcs = utilfuncs.UtilFuncs;

import globalConst from "../common/globalConst";
var global = globalConst.GlobalConst;

import { GlobalVar } from "../common/globalvar";

import { KeyGenerator } from "../common/keygenerator";
import { GraphFourDirFeaturePtUtil } from "../graph/datautil/graphfourdirfeatureptutil";
import { CommonSvc } from "./commonsvc";
import { CrossModLineSvc } from "./crossmodlinesvc";
import LGXCOM from '../common/common.js'

const FastGraphOffGap = 60;

class FastToolPanelSvc {
    constructor(mng) {
        this.fastToolPanel = null;
        this.preMouseOnGraph = null;
        this.dataManger = mng;
    }

    actMouseEvent(mousEvt, mousePoint) {
        if (!GlobalVar.easySelMode || !GlobalVar.showFastTool) {
            return;
        }
        let result = null;
        if (mousEvt.type == LGXEnums.LGXMouseMode.mouseMove) {
            this.processMouseMoveFastToolPanel(mousePoint);
        }
        else if (mousEvt.type == LGXEnums.LGXMouseMode.LMouseDown) {
            result = this.sureSelFastTool(mousePoint);
        }
        return result;
    }


    sureSelFastTool(mousePoint) {
        let scaling = this.dataManger.getScaling();
        if (!this.preMouseOnGraph || !this.fastToolPanel) {
            return null;
        }

        console.log("sureSelFastTool:----");
        console.log(mousePoint);
        let result = { tool: 0, action: "none", point: null,symbolUUID:'' };
        let panel = this.fastToolPanel;
        if (panel.checkCanFastCreat(mousePoint, scaling)) {
            let toolInfo = panel.getSelFastToolInfo(mousePoint);
            if (toolInfo.type != -1) {
                if (funcs.mainObjType(toolInfo.type) == global.BaseUnitPolyline) {
                    if (toolInfo.desc != "none") {
                        this.autoGenerateLineConnToOther(toolInfo.desc);
                    }
                }
                else {
                    result.tool = toolInfo.type;
                    result.point = toolInfo.point;
                    result.action = "fast_draw";
                    result.symbolUUID = toolInfo.symbolUUID;
                }
            }
        }

        this.dataManger.recordRepaintScope(this.fastToolPanel);
        this.fastToolPanel.setUseful(2);
        return result;
    }

    actToMouseHover(mousePoint) {
        if (!GlobalVar.easySelMode || !GlobalVar.showFastTool) {
            return 0;
        }
        let ret = 0;
        let graph = this.chkMouseHoverOnGraph(mousePoint);
        if (graph) {
            if (!this.fastToolPanel) {
                let panel = new fasttoolpanel.FastToolPanel(this);
                panel.setObserver(this.dataManger);
                panel.setFinish(1);
                this.fastToolPanel = panel;
                this.fastToolPanel.resetRefGraph(graph);
                this.preMouseOnGraph = graph;
                panel.calScope(1);
            }

            if (this.preMouseOnGraph != graph) {
                this.fastToolPanel.resetRefGraph(graph);
                this.preMouseOnGraph = graph;
            }
            this.fastToolPanel.setUseful(1);
        }
        let panel = this.fastToolPanel;
        if (panel) {
            panel.setCurentTool(this.dataManger.getTool(),this.dataManger.getToolSymbolUUID());
            if (panel.getUseful() == 1) {
                ret = 1;
                panel.resetPos();
                panel.chkHoverOnArrow(mousePoint);
            }
            this.dataManger.recordRepaintScope(this.fastToolPanel);
        }
        return ret;
    }

    processMouseMoveFastToolPanel(mousePoint) {
        let scaling = this.dataManger.getScaling();
        let panel = this.fastToolPanel;
        if (!panel) {
            return;
        }
        if (panel.getUseful() != 1) {
            return;
        }

        //先判读快捷工具栏还应该绑定在前面图形上
        if (panel.chkNeedDisToolPanel(mousePoint)) {
            panel.setCurentTool(this.dataManger.getTool(),this.dataManger.getToolSymbolUUID());
            return;
        }
        else{
            if (this.chkInPanelAndRefGraphMaxZone(panel,mousePoint, scaling)) {
                panel.checkInToolPanelScope(mousePoint, scaling);//检测当前鼠标位置在快速工具栏的哪个快速图标上
                panel.chechInArrowScope(mousePoint, scaling);
                return ;
            }
            else{
                panel.resetDisInfo();
            }
        }

        let graph = this.chkMouseHoverOnGraph(mousePoint);
        if (graph) {
            if (this.preMouseOnGraph != graph) {
                panel.resetRefGraph(graph);
                this.preMouseOnGraph = graph;
                panel.setUseful(2);
                this.dataManger.recordRepaintScope(this.fastToolPanel);
            }
        }
        else if (!graph) {
            if (this.preMouseOnGraph && this.preMouseOnGraph.getUseful() != 1) {
                panel.setUseful(2);
                this.dataManger.recordRepaintScope(this.fastToolPanel);
                return;
            }

            if (this.chkInPanelAndRefGraphMaxZone(panel,mousePoint, scaling)) {
                panel.setUseful(1);
            }
            else {
                panel.setUseful(2);
            }
            this.dataManger.recordRepaintScope(this.fastToolPanel);
        }
        let panelRefGraph = panel.refGraph;
        if (panelRefGraph.getUseful() != 1) {
            panel.setUseful(2);
            this.dataManger.recordRepaintScope(this.fastToolPanel);
        }
        panel.setCurentTool(this.dataManger.getTool(),this.dataManger.getToolSymbolUUID());
    }

    chkMouseHoverOnGraph(mousePoint) {
        let destGraph = null;
        let hoverOnList = [];
        let tAlllGraphList = this.dataManger.getAllVisibleGraphs();
        let count = tAlllGraphList.length;
        for (let i = 0; i < count; i++) {
            let pGraph = tAlllGraphList[i];
            if (pGraph.getUseful() != 1
                || pGraph.getModifing() != 0
                || pGraph.m_graphType == LGXEnums.LGXGraphType.TextGraph_type
                || pGraph.m_graphType == LGXEnums.LGXGraphType.MultiSel_Rect_Type
                || pGraph.m_graphType == LGXEnums.LGXGraphType.FastToolPanel_type
                || pGraph.m_graphType == LGXEnums.LGXGraphType.CommBusGraph_type
                || pGraph.m_graphType == LGXEnums.LGXGraphType.LineGraph_type
                || pGraph.m_graphType == LGXEnums.LGXGraphType.SplineGraph_type) {
                continue;
            }
            let rect = pGraph.getZone();
            if (funcs.chkPtInRect(mousePoint, rect)) {
                hoverOnList.push(pGraph);
            }
        }
        if (hoverOnList.length == 0) {
            return null;
        }
        else if (hoverOnList.length == 1) {
            return hoverOnList[0];
        }
        if (hoverOnList.length > 1) {
            //距离排序
            let sortedList = hoverOnList.sort(function (p1, p2) {
                if ((p1.getZone().area() - p2.getZone().area()) > 0) {
                    return 1;
                }
                else {
                    return -1;
                }
            }
            );
            destGraph = sortedList[0];
        }

        return destGraph;
    }

    notifyGenerateFastGraph() {
        let pNewGraph = this.dataManger.getCurentGraph();
        let preGraph = this.preMouseOnGraph;
        let ret = this.getAutoLineStAndEndPt(preGraph, pNewGraph);
        if (ret && ret.st && ret.end) {
            let stPt = ret.st;
            let endPt = ret.end;
            let newLineGraph = this.creatNewLineGraph(stPt, endPt);
            if (newLineGraph) {
                //建立连接
                this.connectTwoEndGraph2NewLine(newLineGraph, preGraph, pNewGraph, stPt, endPt);
            }
        }
    }

    connectTwoEndGraph2NewLine(connLineGraph, stGraph, endGraph, stPt, endPt) {
        this.connectGraph2NewLine(connLineGraph, stGraph, stPt);
        this.connectGraph2NewLine(connLineGraph, endGraph, endPt);

        CrossModLineSvc.modifyEnd(connLineGraph, stPt, stPt, 0);
    }


    connectGraph2NewLine(connLineGraph, destGraph, connPt) {
        let topoManager = this.dataManger.getTopoManager();
        var lineRes = connLineGraph.getTopoRes();
        var destRes = destGraph.getTopoRes();
        if (lineRes && destRes) {
            let connNode = topoManager.createNewNode();
            connNode.id = funcs.generateUUID();
            lineRes.addNode4Edit(connNode, connPt);
            destRes.addNode(connNode);
            connNode.setPos(connPt.x, connPt.y);
        }
    }

    getAutoLineStAndEndPt(preGraph, pNextGraph) {
        let cnt1 = preGraph.getZone().getCnt();
        let cnt2 = pNextGraph.getZone().getCnt();
        let dis = funcs.distancePoint(cnt1, cnt2, 1);
        if (dis < global.ZERO_8E) {
            return null;
        }
        let lineDir = funcs.getVector(cnt1, cnt2);
        let lineDegree = lineDir.angleFrmXAxisPositiveDir();

        let st = null;
        let end = null;
        if ((lineDegree >= 0 && lineDegree <= 45) || (lineDegree >= 315 && lineDegree <= 360)) {
            st = GraphFourDirFeaturePtUtil.getEastFeaturePt(preGraph);
            end = GraphFourDirFeaturePtUtil.getWestFeaturePt(pNextGraph);
        }
        else if ((lineDegree >= 45 && lineDegree <= 135)) {
            st = GraphFourDirFeaturePtUtil.getNorthFeaturePt(preGraph);
            end = GraphFourDirFeaturePtUtil.getSouthFeaturePt(pNextGraph);
        }
        else if ((lineDegree > 135 && lineDegree <= 225)) {
            st = GraphFourDirFeaturePtUtil.getWestFeaturePt(preGraph);
            end = GraphFourDirFeaturePtUtil.getEastFeaturePt(pNextGraph);
        }
        else if ((lineDegree > 225 && lineDegree <= 315)) {
            st = GraphFourDirFeaturePtUtil.getSouthFeaturePt(preGraph);
            end = GraphFourDirFeaturePtUtil.getNorthFeaturePt(pNextGraph);
        }

        return { st, end };
    }

    creatNewLineGraph = function (p0, p1) {
        if (funcs.distancePoint(p0, p1, 1) < global.ZERO_4E) {
            console.log("zero lenth line ,error******************");
            alert("zero lenth line ,error******************");
            return null;
        }
        let toolKind = global.TwoPtline_Topo;
        let pNewLineGraph = this.dataManger.creatNewGraph4InnerSvc(toolKind);
        if (!pNewLineGraph) {
            return null;
        }
        pNewLineGraph.m_gid = KeyGenerator.gid();
        pNewLineGraph.getLineDef().endArrowType = "triangle_mid_fill_close";
        let newPosition = pNewLineGraph.getPos();
        newPosition.clear();

        newPosition.addPoint(p0);
        newPosition.addPoint(p1);
        pNewLineGraph.calScope(1);

        this.dataManger.m_topoManager.productNewRes4NewGraph(pNewLineGraph);
        if (pNewLineGraph.m_topoRes) {
            pNewLineGraph.m_rid = pNewLineGraph.m_topoRes.id;
        }
        return pNewLineGraph;
    }

    notifyToCalFastGraphCNT(panelCnt, graph, fastCreateGraph, autoDir) {
        let refZone = graph.getZone();
        let refWidth = refZone.width();
        let refHeight = refZone.height();

        let dstZone = fastCreateGraph.getZone();
        let dstWidth = dstZone.width();
        let dstHeight = dstZone.height();

        let offsetHornLenth = FastGraphOffGap + (dstWidth + refWidth) / 2;
        let offsetVertLenth = FastGraphOffGap + (dstHeight + refHeight) / 2;

        let x = panelCnt.x + offsetHornLenth * autoDir.m;
        let y = panelCnt.y + offsetVertLenth * autoDir.n;
        let initPt = { x, y };//初始确定坐标点，然后以此为基础迭代检测周边是否有碰撞，如果有则要沿着autoDir左转、右转进行尝试
        let result1 = this.findValiZoneToPlaceFastGraph(initPt, dstWidth, dstHeight, autoDir, 90);
        let result2 = this.findValiZoneToPlaceFastGraph(initPt, dstWidth, dstHeight, autoDir, -90);
        let destPt = result1.pt;
        let dis1 = funcs.distancePoint(initPt, result1.pt, 1);
        let dis2 = funcs.distancePoint(initPt, result2.pt, 1);
        if (dis2 < dis1) {
            destPt = result2.pt;
        }
        return destPt;
    }

    findValiZoneToPlaceFastGraph(prePt, fastGraphWid, fastGraphHgt, autoDir, turnAngle) {
        let destPt = { x: prePt.x, y: prePt.y };
        let dstRect = new LGXCOM.LGXRect();

        let halfWid = fastGraphWid / 2;
        let halfhgt = fastGraphHgt / 2;
        dstRect.left = prePt.x - halfWid;
        dstRect.right = prePt.x + halfWid;
        dstRect.top = prePt.y + halfhgt;
        dstRect.bottom = prePt.y - halfhgt;

        let flag = true;
        let ret = this.getOverlapOtherGraph(dstRect);
        if (ret.flag) {
            flag = false;
            // console.log("overlap ********************");
            let nextChkPt1 = this.findNextValiZoneCntToPlaceFastGraph(prePt, fastGraphWid, fastGraphHgt, autoDir,
                ret.conflictRect, turnAngle);

            let nextResult = this.findValiZoneToPlaceFastGraph(nextChkPt1, fastGraphWid, fastGraphHgt, autoDir, turnAngle);
            if (nextResult.flag) {
                flag = true;
                destPt = nextResult.pt;
            }
        }

        return { flag, pt: destPt };
    }

    findNextValiZoneCntToPlaceFastGraph(prePt, fastGraphWid, fastGraphHgt, autoDir, conflictRect, turnAngle) {
        let nextChkPt = { x: 0, y: 0 };

        let turnDir = autoDir.rotateCopy(turnAngle);
        if (Math.abs(turnDir.m - 1) < global.ZERO_4E) {
            nextChkPt.y = prePt.y;
            nextChkPt.x = conflictRect.right + FastGraphOffGap + fastGraphWid / 2;
        }
        else if (Math.abs(turnDir.m + 1) < global.ZERO_4E) {
            nextChkPt.y = prePt.y;
            nextChkPt.x = conflictRect.left - FastGraphOffGap - fastGraphWid / 2;
        }
        else if (Math.abs(turnDir.n - 1) < global.ZERO_4E) {
            nextChkPt.y = conflictRect.top + FastGraphOffGap + fastGraphHgt / 2;
            nextChkPt.x = prePt.x;
        }
        else if (Math.abs(turnDir.n + 1) < global.ZERO_4E) {
            nextChkPt.y = conflictRect.bottom - FastGraphOffGap - fastGraphHgt / 2;
            nextChkPt.x = prePt.x;
        }

        return nextChkPt;
    }


    getOverlapOtherGraph(dstRect) {
        let flag = false;
        let conflictRect = null;
        let confilictLst = [];
        let tAlllGraphList = this.dataManger.getAllGraphs();
        let count = tAlllGraphList.length;
        for (let i = 0; i < count; i++) {
            let pGraph = tAlllGraphList[i];
            if (pGraph.getUseful() != 1
                || pGraph.m_graphType == LGXEnums.LGXGraphType.TextGraph_type
                || pGraph.m_graphType == LGXEnums.LGXGraphType.MultiSel_Rect_Type
                || pGraph.m_graphType == LGXEnums.LGXGraphType.FastToolPanel_type
                || pGraph.m_graphType == LGXEnums.LGXGraphType.LineGraph_type) {
                continue;
            }
            let rect = pGraph.getZone();
            if (funcs.chkOverlap(dstRect, rect)) {
                if (confilictLst.indexOf(pGraph) == -1) {
                    flag = true;
                    confilictLst.push(pGraph);
                }
            }
        }
        if (confilictLst.length > 0) {
            conflictRect = CommonSvc.calGraphsZone(confilictLst);
        }
        return { flag, conflictRect };
    }

    autoGenerateLineConnToOther(dirDesc) {
        let preGraph = this.preMouseOnGraph;
        let preGraphCnt = preGraph.getZone().getCnt();
        let pNextGraph = this.getNextGraph(preGraph, preGraphCnt, dirDesc);
        if (!pNextGraph) {
            return;
        }

        let ret = this.getAutoLineStAndEndPt(preGraph, pNextGraph);
        if (ret && ret.st && ret.end) {
            let stPt = ret.st;
            let endPt = ret.end;
            let newLineGraph = this.creatNewLineGraph(stPt, endPt);
            if (newLineGraph) {
                //建立连接
                this.connectTwoEndGraph2NewLine(newLineGraph, preGraph, pNextGraph, stPt, endPt);
            }
        }
    }

    getNextGraph(preGraph, preGraphCnt, dirDesc) {
        let flag = false;
        const gap = 10;
        let confilictLst = [];
        let tAlllGraphList = this.dataManger.getAllGraphs();
        let count = tAlllGraphList.length;
        for (let i = 0; i < count; i++) {
            let pGraph = tAlllGraphList[i];
            if (preGraph == pGraph
                || pGraph.getUseful() != 1
                || pGraph.m_graphType == LGXEnums.LGXGraphType.MultiSel_Rect_Type
                || pGraph.m_graphType == LGXEnums.LGXGraphType.FastToolPanel_type
                || pGraph.m_graphType == LGXEnums.LGXGraphType.LineGraph_type
                || pGraph.m_graphType == LGXEnums.LGXGraphType.TextGraph_type) {
                continue;
            }
            let rect = pGraph.getZone();
            let nextPt = { x: 0, y: 0 };
            if (dirDesc == "left") {
                nextPt.x = rect.left - gap;
                nextPt.y = preGraphCnt.y;
            }
            else if (dirDesc == "right") {
                nextPt.x = rect.right + gap;
                nextPt.y = preGraphCnt.y;
            }
            else if (dirDesc == "top") {
                nextPt.y = rect.top + gap;
                nextPt.x = preGraphCnt.x;
            }
            else if (dirDesc == "bottom") {
                nextPt.y = rect.top - gap;
                nextPt.x = preGraphCnt.x;
            }

            let rst = funcs.chkLineSecInterRect(preGraphCnt, nextPt, rect);
            if (rst && rst.flag) {
                if (confilictLst.indexOf(pGraph) == -1) {
                    flag = true;
                    let dis = funcs.distancePoint(preGraphCnt, rst.pt, 1);
                    confilictLst.push({ graph: pGraph, dis });
                }
            }
        }
        let destGraph = null;
        if (confilictLst.length > 0) {
            destGraph = confilictLst[0].graph;
            let mindis = confilictLst[0].dis;
            for (let i = 1; i < confilictLst.length; i++) {
                let t = confilictLst[i];
                if (mindis > t.dis) {
                    destGraph = t.graph;
                    mindis = t.dis;
                }
            }
        }
        return destGraph;
    }

    display(painter, displayMng, mapInfo) {
        if (this.fastToolPanel && this.fastToolPanel.getUseful() == 1) {
            displayMng.displaySimulateToolBarOnMap(this.fastToolPanel, painter, mapInfo);
        }
    }

    chkFastToolPanelShow() {
        return (this.fastToolPanel && this.fastToolPanel.getUseful() == 1);
    }

    hideFastPanel() {
        if (this.fastToolPanel && this.fastToolPanel.getUseful() == 1) {
            this.fastToolPanel.setUseful(2);
        }
    }

    chkInPanelAndRefGraphMaxZone(panel,mousePoint, scaling){
        let panelRefGraph = panel.refGraph;
        let rect1 = panelRefGraph.getZone();
        let panelInfo = panel.getToolPanelInfo();
        let rect2 = panelInfo.rect;

        let newRect = new LGXCOM.LGXRect();
        newRect.left = Math.min(rect1.left,rect2.left);
        newRect.right = Math.max(rect1.right,rect2.right);
        newRect.top = Math.max(rect1.top,rect2.top);
        newRect.bottom = Math.min(rect1.bottom,rect2.bottom);
        let flag = funcs.chkPtInRect(mousePoint,newRect);
        let count = 0;
        if (flag){
            count = 1;
        }
        else{
            count = 0;
        }
        console.log(count++);
        return flag;
    }
}

export { FastToolPanelSvc }